package com.sec.bnjey;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.Toast;

import com.sec.bnjey.activity.MainActivity;
import com.sec.bnjey.activity.RegDevSerialnoActivity;
import com.sec.bnjey.activity.UserAgreementActivity;
import com.sec.bnjey.activity.dialog.IKPopup;
import com.sec.bnjey.activity.dialog.IKPopup.Builder.onIKPopupClickListener;
import com.sec.bnjey.bluetooth.BtService;
import com.sec.bnjey.global.Const;
import com.sec.bnjey.global.GlobalApplication;
import com.sec.bnjey.global.RbPreference;
import com.sec.bnjey.svc.DaemonService;
import com.sec.bnjey.utils.RbLog;

public class IntroActivity extends Activity implements OnClickListener {

	private static final String TAG = "IntroActivity";

	private IntroStepHandler mIntroHandler;
	private ProgressUpdateHandler mProgressUpdateHandler;
	boolean regUserAgreement;
	boolean regCarInfo;
	private static final int PAIRINGPOPUP_TIMEOUT_SEC = 11;

	// progress ui
	private ImageView iv_loading;
	private int mProgressVal;
	private SeekBar sb_loading;
	WakeLock wakeLock = null;
	private int PROGRESS_IMG_BLUETOOTH = 0;
	private int PROGRESS_IMG_OBD_CHECK = 1;
	private int PROGRESS_IMG_COMMUNICATION = 2;
	private int PROGRESS_IMG_CONNECTING = 3;

	private ProgressDialog mProgressDialog;

	private int mProgressCurrentImage = PROGRESS_IMG_BLUETOOTH;

	private TypedArray mNumImage;

	int mCurrentStep;

	final static private int INTRO_STEP_READY = 0;
	final static private int INTRO_STEP_CONNECTION_INIT = 10;
	final static private int INTRO_STEP_CONNECTION = 11;
	final static private int INTRO_STEP_POPUP = 20;
	final static private int INTRO_STEP_REGISTER = 30;
	final static private int INTRO_STEP_COMPLETE = 40;
	final static private int INTRO_STEP_REGISTER_AGREEMENT = 50;
	final static private int INTRO_STEP_REGISTER_CARINFO = 60;

	private static final int MAX_PROGRESS_STEP = 100;

	int mConnectionTimeoutCnt;
	RbPreference mRbPref;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		RbLog.d(TAG, "onCreate");

		setContentView(R.layout.introactivity);

		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

		mRbPref = new RbPreference(IntroActivity.this);

		if (Const.TESTMODE == true) {
			Toast.makeText(getApplicationContext(), "테스트 모드입니다.",
					Toast.LENGTH_LONG).show();

			startActivity(new Intent(IntroActivity.this, MainActivity.class));

			overridePendingTransition(0, 0);
			finish();

		} else {

			mRbPref.update(RbPreference.PREF_RUN_WITHOUT_OBD, false);

			// make enable bluetooth
			boolean btOldStatus = BtService.getBtService().enable();
			GlobalApplication.setBluetoothOldStatus(btOldStatus);
			mIntroHandler = new IntroStepHandler();

			if (btOldStatus == false) {
				mIntroHandler.sendEmptyMessageDelayed(INTRO_STEP_READY, 3000);

			} else {
				mIntroHandler.sendEmptyMessageDelayed(INTRO_STEP_READY, 1000);

			}

			mProgressUpdateHandler = new ProgressUpdateHandler();
			mProgressUpdateHandler.sendEmptyMessage(0);

			showInitDialog();
		}
		viewInit();
	}

	private void showInitDialog() {
		mProgressDialog = ProgressDialog.show(IntroActivity.this, "",
				"loading...", true);

	}

	public void changeToWakeMode() {
		RbLog.d(TAG, " --- ---  WAKE_MODE_ON  --- --- ");
		if (wakeLock == null) {
			PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
			wakeLock = powerManager.newWakeLock(
					PowerManager.SCREEN_DIM_WAKE_LOCK, "wakelock");
			wakeLock.acquire();
		}
	}

	private void viewInit() {

		mProgressVal = 0;
		sb_loading = (SeekBar) findViewById(R.id.sb_loading);
		sb_loading.setMax(MAX_PROGRESS_STEP);

		iv_loading = (ImageView) findViewById(R.id.iv_loading);
		mNumImage = getResources().obtainTypedArray(R.array.array_LoadingText);
		iv_loading.setBackgroundDrawable(mNumImage
				.getDrawable(mProgressCurrentImage));
		changeToWakeMode();
	}

	@Override
	protected void onDestroy() {

		super.onDestroy();
	}

	@Override
	protected void onPause() {
		super.onResume();
		RbLog.d(TAG, "onPause");

		mProgressDialog.dismiss();
		mIntroHandler.removeCallbacksAndMessages(null);
		if (wakeLock != null) {
			wakeLock.release();
			RbLog.d(TAG, " --- ---  WAKE_MODE_OFF  --- --- ");
			wakeLock = null;
		}
	}

	@Override
	protected void onResume() {
		super.onResume();

		mIntroHandler.sendEmptyMessage(0);

		RbLog.d(TAG, "onResume");

	}

	int retryConut = 0;

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);

		RbLog.d(TAG, "onActivityResult " + requestCode);

		if (requestCode == INTRO_STEP_CONNECTION) {

			setStep(INTRO_STEP_CONNECTION_INIT, 1000);

		} else if (requestCode == INTRO_STEP_REGISTER_AGREEMENT) {
			int error_code = 0;
			try {
				mRbPref.update(RbPreference.PREF_INTRO_USER_AGREEMENT, true);

			} catch (Exception e) {
				// TODO: handle exception
			}
			if (error_code == -1) {
				RbLog.d(TAG, "error_code -1");
				retryConut++;
				if (retryConut < 3) {
					setStep(INTRO_STEP_READY, 1000);
				} else {

					Toast.makeText(getApplicationContext(),
							"OBD 통신이 불가하여 종료합니다.", Toast.LENGTH_LONG).show();
					finish();
					exitProgram();
				}
			} else {
				setStep(INTRO_STEP_REGISTER, 1000);
			}
		} else if (requestCode == INTRO_STEP_REGISTER_CARINFO) {
			int error_code = 0;
			try {
				mRbPref.update(RbPreference.PREF_INTRO_REGISTER_CARINF1, true);

			} catch (Exception e) {
				// TODO: handle exception
			}
			if (error_code == -1) {
				RbLog.d(TAG, "error_code -1");
				retryConut++;
				if (retryConut < 3) {
					setStep(INTRO_STEP_READY, 1000);
				} else {

					Toast.makeText(getApplicationContext(),
							"OBD 통신이 불가하여 종료합니다.", Toast.LENGTH_LONG).show();
					finish();
					exitProgram();
				}
			} else {
				setStep(INTRO_STEP_REGISTER, 1000);
			}
		}
	}

	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		RbLog.d(TAG, "onWindowFocusChanged " + hasFocus);
		super.onWindowFocusChanged(hasFocus);
	}

	private void popupPairingDialog() {

		RbLog.d(TAG, "popupPairingDialog");

		final IKPopup.Builder popup = new IKPopup.Builder(this,
				IKPopup.POPUP_INFO_TWO_BTN,
				getString(R.string.popup_type_information),
				getString(R.string.popup_pairing_require),
				getString(R.string.btn_yes), getString(R.string.btn_no));

		final Dialog dlg = popup.create();
		popup.setOnIKPopuoClickListener(new onIKPopupClickListener() {
			@Override
			public void onIKPopUpClick(View v) {
				switch (v.getId()) {

				case R.id.B_Popup_Ok:
					dlg.dismiss();
					Intent intentBluetooth = new Intent();
					intentBluetooth
							.setAction(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
					startActivityForResult(intentBluetooth,
							INTRO_STEP_CONNECTION);
					break;

				case R.id.B_Popup_Cancel:
					dlg.dismiss();
					exitProgram();
					break;
				}
			}
		});
		dlg.setCancelable(false);
		dlg.show();
	}

	private void popupTimeoutDialog() {

		RbLog.d(TAG, "popupTimeoutDialog");

		final IKPopup.Builder popup = new IKPopup.Builder(IntroActivity.this,
				IKPopup.POPUP_INFO_TWO_BTN,
				getString(R.string.popup_type_information),
				getString(R.string.popup_commerror_body),
				getString(R.string.btn_yes), getString(R.string.btn_no));
		final Dialog dlg = popup.create();
		popup.setOnIKPopuoClickListener(new onIKPopupClickListener() {
			@Override
			public void onIKPopUpClick(View v) {
				switch (v.getId()) {

				case R.id.B_Popup_Ok:
					Intent intent = new Intent(IntroActivity.this,
							MainActivity.class);
					mRbPref.update(RbPreference.PREF_RUN_WITHOUT_OBD, true);
					startActivity(intent);
					finish();

					dlg.dismiss();
					break;

				case R.id.B_Popup_Cancel:
					exitProgram();
					dlg.dismiss();
					break;
				}
			}
		});
		dlg.setCancelable(false);
		dlg.show();
	}

	private void viewUpdateProgressImage(int what) {

		switch (what) {

		case INTRO_STEP_READY:
			mProgressCurrentImage = PROGRESS_IMG_BLUETOOTH;
			break;
		case INTRO_STEP_CONNECTION:
			mProgressCurrentImage = PROGRESS_IMG_BLUETOOTH;
			break;

		case INTRO_STEP_REGISTER:

			mProgressCurrentImage = PROGRESS_IMG_OBD_CHECK;
			break;
		case INTRO_STEP_COMPLETE:
			mProgressCurrentImage = PROGRESS_IMG_COMMUNICATION;

			break;

		}

		iv_loading.setBackgroundDrawable(mNumImage
				.getDrawable(mProgressCurrentImage));
	}

	private void viewUpdateProgressVal(int what) {
		mProgressVal = what * 10;
		sb_loading.setProgress(mProgressVal);
	}

	private class ProgressUpdateHandler extends Handler {

		@Override
		public void handleMessage(Message msg) {

			viewUpdateProgressImage(mCurrentStep);
			viewUpdateProgressVal(mCurrentStep);

			this.sendMessageDelayed(this.obtainMessage(0), 1000);
		}
	}

	private void setStep(int newStep, int delaySec) {

		if (mCurrentStep != INTRO_STEP_CONNECTION && mCurrentStep == newStep)
			return;

		RbLog.d(TAG, "updateCurrentStep " + newStep);

		mCurrentStep = newStep;
		mIntroHandler.removeMessages(0);
		mIntroHandler.sendMessageDelayed(mIntroHandler.obtainMessage(newStep),
				delaySec * 1000);

	}

	private boolean isDaemoServiceRunning() {
		ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
		for (RunningServiceInfo service : manager
				.getRunningServices(Integer.MAX_VALUE)) {
			if ("com.bnjey.vtalk.svc.DaemonService".equals(service.service
					.getClassName())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 
	 * intro handler
	 * 
	 * @author sj.okay
	 * 
	 */
	private class IntroStepHandler extends Handler {

		@Override
		public void handleMessage(Message msg) {

			RbLog.d(TAG, "=== IntroHandler Step : " + mCurrentStep);

			switch (mCurrentStep) {

			// intro start
			// make enable bluetooth,
			// verify daemon service is stop
			case INTRO_STEP_READY: {
				RbLog.d(TAG, "INTRO_STEP_READY");

				// wait daemon close
				if (isDaemoServiceRunning() == false
						&& BtService.getBtService().isEnable()) {

					BtService.getBtService().start();
					mConnectionTimeoutCnt = 0;

					if (BtService.getBtService().hasLastDevice()) {
						setStep(INTRO_STEP_CONNECTION_INIT, 1);
					} else {
						popupPairingDialog();
						BtService.getBtService().connectionThreadStop();
						setStep(INTRO_STEP_POPUP, 1);
					}

				} else {
					RbLog.d(TAG, "Wait for daemon close");
					mIntroHandler.sendMessageDelayed(
							mIntroHandler.obtainMessage(INTRO_STEP_READY),
							1 * 1000);

					stopService(new Intent(IntroActivity.this,
							DaemonService.class));
				}

				break;
			}

			case INTRO_STEP_CONNECTION_INIT: {
				mConnectionTimeoutCnt = 0;
				// connected. kip this step
				if (BtService.getBtService().getBluetoothStatus() == BtService.STATE_CONNECTED) {
					setStep(INTRO_STEP_REGISTER, 1);
					break;
				}

				BtService.getBtService().connectionStart();
			}

			// connection
			case INTRO_STEP_CONNECTION: {
				RbLog.d(TAG, "INTRO_STEP_CONNECTION");

				mConnectionTimeoutCnt++;
				RbLog.d(TAG, "mConnectionTimeoutCnt " + mConnectionTimeoutCnt);

				// testmode
				if (Const.TESTMODE_PASS_OBD_CONNECTION) {
					RbLog.d(TAG, "TEST MODE PASS");
					setStep(INTRO_STEP_REGISTER, 1);
					break;
				}

				// connected. skip this step
				if (BtService.getBtService().getBluetoothStatus() == BtService.STATE_CONNECTED) {
					setStep(INTRO_STEP_REGISTER, 1);
					break;
				}

				RbLog.d(TAG, "Bluetooth Status "
						+ BtService.getBtService().getBluetoothStatus());

				switch (BtService.getBtService().getBluetoothStatus()) {
				// we're doing nothing
				case BtService.STATE_NONE:
					break;
				// now initiating an outgoing connection
				case BtService.STATE_CONNECTING:
					break;
				case BtService.STATE_PAIRING:
					break;
				default:
					break;
				}

				if (mConnectionTimeoutCnt < 50) {
					// verify connection timeout
					if (mConnectionTimeoutCnt == PAIRINGPOPUP_TIMEOUT_SEC) {
						BtService.getBtService().connectionThreadStop();
						popupTimeoutDialog();
						setStep(INTRO_STEP_POPUP, 1);
					} else {
						setStep(INTRO_STEP_CONNECTION, 1);
					}
				} else {
					exitProgram();
				}
				break;
			}

			case INTRO_STEP_POPUP: {

				break;
			}

			// register user info.
			case INTRO_STEP_REGISTER: {
				RbLog.d(TAG, "INTRO_STEP_REGISTER");

				Intent intent = null;

				RbLog.d(TAG, "Bluetooth Status "
						+ BtService.getBtService().getBluetoothStatus());

				// check connection
				if (BtService.getBtService().getBluetoothStatus() != BtService.STATE_CONNECTED) {
					RbLog.e(TAG,
							"Connection Lost. go to INTRO_STEP_CONNECTION_INIT");
					BtService.getBtService().stop();
					setStep(INTRO_STEP_CONNECTION_INIT, 1);
					break;
				}

				if (Const.TESTMODE_PASS == true) {
					RbLog.d(TAG, "TEST MODE PASS");
					setStep(INTRO_STEP_COMPLETE, 1);
				} else {

					regUserAgreement = mRbPref.getValue(
							RbPreference.PREF_INTRO_USER_AGREEMENT, false);
					regCarInfo = mRbPref.getValue(
							RbPreference.PREF_INTRO_REGISTER_CARINF1, false);

					RbLog.d(TAG, "regUserAgreement " + regUserAgreement);
					RbLog.d(TAG, "regCarInfo " + regCarInfo);

					int requestCode = 0;
					// UserAgreement
					if (regUserAgreement == false) {
						intent = new Intent(IntroActivity.this,
								UserAgreementActivity.class);
						requestCode = INTRO_STEP_REGISTER_AGREEMENT;
					}
					// Register Car Info1
					else if (regCarInfo == false) {
						intent = new Intent(IntroActivity.this,
								RegDevSerialnoActivity.class);
						requestCode = INTRO_STEP_REGISTER_CARINFO;
					}

					if (intent != null) {
						startActivityForResult(intent, requestCode);
					} else {
						setStep(INTRO_STEP_COMPLETE, 1);
					}
					overridePendingTransition(0, 0);
				}

				break;
			}

			case INTRO_STEP_COMPLETE:

				if (BtService.getBtService().isOBDDeviceConnected() == false) {
					setStep(INTRO_STEP_CONNECTION, 1);
					break;
				}

				startActivity(new Intent(IntroActivity.this, MainActivity.class));

				overridePendingTransition(0, 0);
				finish();
				break;

			}
			super.handleMessage(msg);
		}
	}

	@Override
	public void onClick(View v) {
	}

	@Override
	public void onBackPressed() {
		exitProgram();
	}

	private void exitProgram() {
		mIntroHandler.removeCallbacksAndMessages(null);

		GlobalApplication.stopBluetoothService();
		finish();
	}

}